package com.yvdelx.cyclowomen.activity.adapter;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;

import com.yvdelx.R;
import com.yvdelx.cyclowomen.activity.DayConsultationActivity;
import com.yvdelx.cyclowomen.activity.DayModificationActivity;
import com.yvdelx.cyclowomen.mediation.CycleManagement;
import com.yvdelx.cyclowomen.object.Cycle;
import com.yvdelx.cyclowomen.object.Day;
import com.yvdelx.cyclowomen.utility.DateUtility;
import com.yvdelx.cyclowomen.utility.LogUtility;
import com.yvdelx.cyclowomen.utility.StringUtility;
import com.yvdelx.cyclowomen.utility.ViewUtility;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import static com.yvdelx.cyclowomen.utility.StringUtility.CST_BUNDLE;
import static com.yvdelx.cyclowomen.utility.StringUtility.CST_COLOR_BLUE;
import static com.yvdelx.cyclowomen.utility.StringUtility.CST_COLOR_CURRENT_DATE;
import static com.yvdelx.cyclowomen.utility.StringUtility.CST_COLOR_GREEN;
import static com.yvdelx.cyclowomen.utility.StringUtility.CST_COLOR_GREY;
import static com.yvdelx.cyclowomen.utility.StringUtility.CST_COLOR_ORANGE;
import static com.yvdelx.cyclowomen.utility.StringUtility.CST_COLOR_RED;
import static com.yvdelx.cyclowomen.utility.StringUtility.CST_COLOR_WHITE;
import static com.yvdelx.cyclowomen.utility.StringUtility.CST_DATE;

/**
 * Adapter for the calendar activity/view
 * Created by ydelvaux on 25/02/14.
 */
public class GridCellAdapter extends BaseAdapter implements View.OnClickListener {

    private final Context mContext;

    private final Activity activity;

    private final List<String> listCellParameter;

    private static final int DAY_OFFSET = 1;

    private Integer currentDayOfMonth;

    public GridCellAdapter(Context context,
                           Integer month,
                           Integer year,
                           Activity activity) throws ParseException {

        super();
        this.mContext = context;
        this.listCellParameter = new ArrayList<String>();
        this.activity = activity;
        Calendar calendar=Calendar.getInstance();
        this.currentDayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);

        // Print Month
        printMonth(month,year);
    }

    /**
     * Return the parameter of a day (colour)
     * @param position item position in the grid cell
     * @return parameter
     */
    public String getItem(int position){
        return listCellParameter.get(position);
    }

    /**
     * Return number of cells used
     * @return number
     */
    @Override
    public int getCount(){
        return listCellParameter.size();
    }

    /**
     * Print Month (Integer month, Integer year)
     * @param month month
     * @param year year
     */
    private void printMonth(Integer month, Integer year) throws ParseException {

        try {

            LogUtility.debug(this.getClass(), "print : " + month + "/" + year);

            Integer daysInPrevMonth;
            Integer prevMonth;
            Integer prevYear;
            Integer nextMonth;
            Integer nextYear;

            // Get number days of a month
            Integer daysInMonth = DateUtility.getNumberOfDayOfMonth(year, month);
            LogUtility.debug(this.getClass(), "Number days in month : " + daysInMonth);

            // If it's the december month
            if (month == 12) {
                prevMonth = month - 1;
                nextMonth = 1;
                prevYear = year;
                nextYear = year + 1;
                daysInPrevMonth = DateUtility.getNumberOfDayOfMonth(prevYear, prevMonth);
            } else if (month == 0) { // If it's the january month
                prevMonth = 12;
                nextMonth = month + 1;
                prevYear = year - 1;
                nextYear = year;
                daysInPrevMonth = DateUtility.getNumberOfDayOfMonth(prevYear, prevMonth);
            } else { // If it's an other month
                prevMonth = month - 1;
                nextMonth = month + 1;
                nextYear = year;
                prevYear = year;
                daysInPrevMonth = DateUtility.getNumberOfDayOfMonth(prevYear, prevMonth);
            }

            LogUtility.debug(this.getClass(), "Previous month : " + prevMonth);
            LogUtility.debug(this.getClass(), "Previous year : " + prevYear);
            LogUtility.debug(this.getClass(), "Days in previous month : " + daysInPrevMonth);
            LogUtility.debug(this.getClass(), "Next month : " + nextMonth);
            LogUtility.debug(this.getClass(), "Next year : " + nextYear);

            GregorianCalendar cal = new GregorianCalendar(year, month - 1, 1);
            Integer trailingSpaces = cal.get(Calendar.DAY_OF_WEEK) - 1;
            LogUtility.debug(this.getClass(), "Trailing spaces : " + trailingSpaces);

            // If it's a leap year
            if (cal.isLeapYear(cal.get(Calendar.YEAR)))
                // If it's february month
                if (month == 2)
                    ++daysInMonth;
                else if (month == 3) // If it's march month
                    ++daysInPrevMonth;


            // Draw previous month day
            for (int i = 0; i < trailingSpaces; i++) {
                listCellParameter.add(parameterToString((daysInPrevMonth - trailingSpaces + DAY_OFFSET) + i,
                        prevMonth, prevYear, CST_COLOR_GREY));
            }

            Date date;
            Cycle currentCycle = CycleManagement.getCycleCurrent();
            // To draw current Month Days
            for (int i = 1; i <= daysInMonth; i++) { // i = day of month
                date = DateUtility.getDate(i, month - 1, year);
                LogUtility.debug(this.getClass(), DateUtility.dateToString(date));
                Cycle cycle = CycleManagement.getCycle(date);
                Day day;
                if (cycle == null)
                    day = null;
                else {

                    if(currentCycle != null && !currentCycle.equals(cycle)){
                        CycleManagement.changeCurrentCycle(cycle);
                        currentCycle = cycle;
                    }

                    day = CycleManagement.getDay(date, cycle);
                    LogUtility.debug(this.getClass(), "Cycle ID : " + cycle.getIdCycle());
                }

                String color;

                if (day != null && day.getSensation() != null) {

                    LogUtility.debug(this.getClass(), "Day exist !");

                    if (day.getSensation().isMenses()) {
                        // Menses day
                        color = CST_COLOR_RED;
                    } else if (CycleManagement.isFertileDay(day)) {
                        // Fertile day
                        color = CST_COLOR_BLUE;
                    } else {
                        // Not fertile day
                        color = CST_COLOR_GREEN;
                    }

                    if (!day.getIsNominalCondition()) {
                        color = CST_COLOR_ORANGE;
                    }

                } else {
                    if (i == this.currentDayOfMonth && DateUtility.isCurrentMonth(month)) {
                        color = CST_COLOR_CURRENT_DATE;
                    } else {
                        color = CST_COLOR_WHITE;
                    }
                }


                listCellParameter.add(parameterToString(i, month, year, color));

            }

            // To draw next Month days
            for (int i = 1; i < listCellParameter.size() % 7; i++) {
                listCellParameter.add(parameterToString(i, nextMonth, nextYear, CST_COLOR_GREY));
            }

            try {
                Cycle cycle = CycleManagement.getCycleCurrent();
                if (cycle != null) {
                    ViewUtility.setTextInTextView(activity.findViewById(R.id.LowAverageTextView),
                            activity.getResources().getString(R.string.lowAverageTemperature)
                                    + " "
                                    + StringUtility.formatDouble(cycle.getAverageLowTemperature())
                                    + activity.getResources().getString(R.string.degree)
                    );

                    ViewUtility.setTextInTextView(activity.findViewById(R.id.HightAverageTemperatureTextView),
                            activity.getResources().getString(R.string.highAverageTemperature)
                                    + " "
                                    + StringUtility.formatDouble(cycle.getAverageHighTemperature())
                                    + activity.getResources().getString(R.string.degree)
                    );
                }
            } catch (Exception e) {
                LogUtility.error(this.getClass(), e.getMessage(), e);
            }
        } catch(Exception ex){
            LogUtility.error(this.getClass(),ex.getMessage(),ex);
        }
    }

    @Override
    public long getItemId(int position){
        return position;
    }


    // Draw the cell content
    @Override
    public View getView(int position, View row, ViewGroup parent){
        if(row == null){
            LayoutInflater inflater=(LayoutInflater)mContext
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.screen_gridcell,parent,false);
        }

        if(row == null)
            return null;

        // Get a reference to the Day gridCell
        Button gridCell=(Button) row.findViewById(R.id.calendar_day_gridcell);
        gridCell.setOnClickListener(this);

        // Get day color
        String[] day_color= listCellParameter.get(position).split("-");
        String theDay = day_color[0];
        String theMonth = day_color[2];
        String theYear = day_color[3];

        // Set the Day GridCell
        gridCell.setText(theDay);
        try {
            Date dateTag = DateUtility.getDate(Integer.valueOf(theDay),
                    Integer.valueOf(theMonth),
                    Integer.valueOf(theYear));
            gridCell.setTag(DateUtility.dateToString(dateTag));
        } catch (ParseException e) {
            LogUtility.error(this.getClass(),e.getMessage(),e);
        }

        Resources resources = parent.getResources();

        // Color the grid with the color from the resources
        if(resources != null) {
            if(day_color[1].equals(CST_COLOR_GREY))
                gridCell.setTextColor(resources.getColor(R.color.lightgray));

            if(day_color[1].equals(CST_COLOR_WHITE))
                gridCell.setTextColor(resources.getColor(R.color.lightgray02));

            if(day_color[1].equals(CST_COLOR_BLUE)){
                gridCell.setBackground(resources.getDrawable(R.drawable.calendar_button_selector_blue));
                gridCell.setTextColor(resources.getColor(R.color.white));
            }

            if(day_color[1].equals(CST_COLOR_CURRENT_DATE))
                gridCell.setTextColor(resources.getColor(R.color.orrange));

            if(day_color[1].equals(CST_COLOR_GREEN)){
                gridCell.setBackground(resources.getDrawable(R.drawable.calendar_button_selector_green));
                gridCell.setTextColor(resources.getColor(R.color.black_overlay));
            }

            if(day_color[1].equals(CST_COLOR_RED)) {
                gridCell.setBackground(resources.getDrawable(R.drawable.calendar_button_selector_red));
                gridCell.setTextColor(resources.getColor(R.color.white));
            }

            if(day_color[1].equals(CST_COLOR_ORANGE)) {
                gridCell.setBackground(resources.getDrawable(R.drawable.calendar_bg_orange));
                gridCell.setTextColor(resources.getColor(R.color.white));
            }
        }

        return row;
    }

    @Override
    public void onClick(View view){
        String date_month_year=(String) view.getTag();
        LogUtility.debug(this.getClass(), "Selected date : " + date_month_year);
        try{
            Date parsedDate = DateUtility.getDateFromString(date_month_year);
            LogUtility.debug(this.getClass(), "Parsed Date : " + parsedDate.toString());

            Cycle cycle = CycleManagement.getCycle(parsedDate);

            CycleManagement.changeCurrentCycle(cycle);

            // Choose between Day Modification and Day Consultation
            Intent intent;
            if(cycle != null && CycleManagement.getDay(parsedDate,cycle) != null)
                intent = new Intent(mContext, DayConsultationActivity.class);
            else
                intent = new Intent(mContext, DayModificationActivity.class);

            Bundle bundle = new Bundle();
            bundle.putLong(CST_DATE, DateUtility.getLongFromDate(parsedDate));
            intent.putExtra(CST_BUNDLE, bundle);
            this.activity.startActivity(intent);

        }catch(ParseException e){
            LogUtility.error(this.getClass(), e.getMessage(), e);
            ((Activity) mContext).finish();
        } catch (Exception e) {
            LogUtility.error(this.getClass(), e.getMessage(), e);
            ((Activity) mContext).finish();
        }
    }

    /**
     * Put in a String all parameter for a day
     * @param day Integer
     * @param month Integer
     * @param year Integer
     * @param color Month
     * @return String
     */
    private String parameterToString(Integer day, Integer month, Integer year, String color){
        return String.valueOf(day) + "-" + color + "-" + DateUtility.getMonthNumberAsString(month) + "-" + year;
    }
}

